package com.bjsxt.livegoods.es.dao.impl;

import com.bjsxt.livegoods.es.dao.ProductDao4ES;
import com.bjsxt.livegoods.es.vo.Product4Search;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.SearchQuery;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 商品数据访问实现-
 */
public class ProductDao4ESImpl implements ProductDao4ES {
    @Autowired
    private ElasticsearchRestTemplate restTemplate;

    public ElasticsearchRestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(ElasticsearchRestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Override
    public void createIndex() {
        restTemplate.createIndex(Product4Search.class);
    }

    @Override
    public void putMapping() {
        restTemplate.putMapping(Product4Search.class);
    }

    @Override
    public void indexDoc(Product4Search product4Search) {
        IndexQuery query = new IndexQueryBuilder().withObject(product4Search).build();
        restTemplate.index(query);
    }

    @Override
    public Map<String, Object> searchProduct(String city, String content, int page, int rows) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must().add(QueryBuilders.matchQuery("city", city));
        queryBuilder.must().add(QueryBuilders.matchQuery("title", content));

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        HighlightBuilder.Field field = new HighlightBuilder.Field("title");

        field.fragmentSize(20);
        field.numOfFragments(1);

        SearchQuery query = new NativeSearchQuery(
                queryBuilder,
                null,
                null,
                highlightBuilder,
                new HighlightBuilder.Field[]{field}
        );
        query.setPageable(
                PageRequest.of(page, rows, Sort.by(Sort.Direction.ASC, "price"))
        );
        List<Product4Search> product4SearchList =
                restTemplate.query(query, new ResultsExtractor<List<Product4Search>>() {
                    @Override
                    public List<Product4Search> extract(SearchResponse searchResponse) {
                        List<Product4Search> result = new ArrayList<>();
                        for (SearchHit hit : searchResponse.getHits().getHits()) {
                            Map<String, HighlightField> highlightFieldMap =
                                    hit.getHighlightFields();
                            Map<String, Object> sourceMap = hit.getSourceAsMap();
                            Product4Search item = new Product4Search();
                            item.setId(sourceMap.get("id").toString());
                            //如果有高亮数据使用高亮数据，没有高亮数据使用原数据
                            if (highlightFieldMap != null && highlightFieldMap.get("title") != null) {
                                //title有高亮数据
                                String highlightTitle = highlightFieldMap.get("title").getFragments()[0].toString();
                                item.setTitle(highlightTitle);
                            } else {
                                //title没有高亮数据
                                item.setTitle(sourceMap.get("title").toString());
                            }
                            item.setTitle(sourceMap.get("title").toString());
                            item.setImg(sourceMap.get("img").toString());
                            item.setPrice(sourceMap.get("price").toString());
                            item.setHouseType(sourceMap.get("houseType").toString());
                            item.setRentType(sourceMap.get("rentType").toString());
                            item.setCity(sourceMap.get("city").toString());
                            result.add(item);
                        }
                        return result;
                    }
                });
        //总计数据的数量
        long count = restTemplate.count(query, Product4Search.class);
        Map<String, Object> result = new HashMap<>();
        result.put("data", product4SearchList);
        result.put("hasMore", (page + 1) * rows < count);
        return result;
    }
}